/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
/**
 *
 * $Id: hubctrlHdr.h,v 1.1 2008-03-30 00:55:36 amaula Exp $
 *
 */
#ifndef _HUBCTRLHDR_H_
#define _HUBCTRLHDR_H_
#include "protocolID.h"
#include <inttypes.h>

// Protocol identification
#define HUBCTRLPROTOCOL_NUMBER                   0x00

//////////////////  HubCtrl - Request numbers //////////////////////////

/**
 * REQUEST_QUERYOWNID
 * - Return value is fully qualified address with HUB and CLIENT parts. Connecting
 * hubs can use this for determining their counterparts HUB address, and connecting
 * clients can determine their own assigned address.
 */
#define HUBCTRL_REQUEST_QUERYOWNID               0x01

/**
 * REQUEST_SETOWNID
 * - Attempts to set this connections ID to 'id'. This is useful for clients
 * who want to keep an constant address (don't want to use name service), and
 * for hubs which can instruct the opposite end hub that this connection is really
 * an HUB trunk.
 *
 * - Clients:
 *   - Use the desired Client_ID as client ID (but NOT 0x0000)
 *   - Use CONNECTIONLIST_HUBIDID_LOCAL (0x0000) as HUB_ID
 * - HUBs:
 *   - Send their OWN HUBID as HUBID
 *   - Send CONNECTIONLIST_CLIENTID_HUB (0x0000) as their CLIENT_ID 
 */
#define HUBCTRL_REQUEST_SETOWNID                 0x02


/**
 * REQUEST_ECHO
 * - HubCtrl ECHO. This message is replied with the same packet
 * only the source and target fields are shifted and REPLY flag set.
 * 
 * - NOTE: Clients using the tcpHub v3.x _must_implement_ the ECHO
 * reply feature, if they do not, they may be dropped from the hub
 * in the future when this becomes automatic feature.
 *
 * - This packet is bidirectional, both; client & hub may initiate
 * this.
 */
#define HUBCTRL_REQUEST_ECHO                     0x03


/**
 * REQUEST_HUBVERSION
 * - This query returns the hub version in data.version structure
 * of the packet.
 *
 * - This packet is unidirectional to HUB, so no client needs to
 * reply to this at any point.
 *
 */
#define HUBCTRL_REQUEST_HUBVERSION               0x04


/**
 * REQUEST_ADDROUTINGENTRY
 * - TBD
 *
 */
#define HUBCTRL_REQUEST_ADDROUTINGENTRY          0x05


/**
 * REQUEST_REMOVEROUTINGENTRY
 * - TBD
 *
 */
#define HUBCTRL_REQUEST_REMOVEROUTINGENTRY       0x06

/**
 * REQUEST_SETDEBUGLVL
 * - Sets the HUB debug level to 'value' specified in 'raw' field.
 * - This packet is unidirectional to HUB, and no reply is generated.
 *
 */
#define HUBCTRL_REQUEST_SETDEBUGLVL              0x07

/// Undefined Request number, also assumed when received number is out of range.
#define HUBCTRL_REQUEST_UNDEFINED                0x00



/**
 * REQUEST_SETLINKDELAY
 * - Sets the current links delay to value in milliseconds specified in the 'delay_ms'
 * field.
 * - No reply is generated
 */
#define HUBCTRL_REQUEST_SETOWNLINKDELAY          0x08



/// Minimum limit for requestnumber
#define HUBCTRL_MINREQUESTNUMBER                 0x01

/// Maximum limit for requestnumber
#define HUBCTRL_MAXREQUESTNUMBER                 0x08

//////////////////  HubCtrl - Flags //////////////////////////////////
#define HUBCTRL_FLAG_REPLY                       0x01
#define HUBCTRL_FLAG_ERROR                       0x02
#define HUBCTRL_FLAG_HUBNEGOTIATION              0x04


/**
 * Protocol header for network traffic
 */
typedef struct _hubctrlProtocolHeader
{
  TProtocolIdentification protocol_id;   ///< Compulsory protocol_id struct (4)
  
  uint16_t request;             ///< Type of request               (2)
  uint16_t flags;               ///< Flags                         (2)
  
  union {
    uint32_t delay_ms;          ///< delay in ms
    uint32_t timestamp_ms;      ///< Timestamp in ms
    uint32_t raw;               ///< Raw 4 bytes
    int32_t signedraw;          ///< Raw 4 bytes signed.
    uint32_t own_id;            ///< Data as 'own_id'
    uint32_t new_id;            ///< Data as 'new_id'

    struct {
      uint8_t major;            ///< Major version. (Probably 3)
      uint8_t minor;            ///< Minor version.
      uint8_t sub;              ///< Sub version (if 0, not printed)
      uint8_t fix;              ///< Fix version (if 0, not printed)
      uint16_t build;           ///< Build number
      uint16_t protocol_ver;    ///< Protocol version
    } version;                  ///< Hub version   
    

    struct {
      uint32_t target;          ///< Routing entry target (to-be-routed...)
      uint32_t gateway;         ///< Routing gateway (transfer link)
    } route;
  } data;                       

} THubCtrlProtocolHeader;
#define SIZEOF_THUBCTRLPROTOCOLHEADER (SIZEOF_TPROTOCOLIDENTIFICATION + 2 + 2 + 8)

#endif
